package br.com.insejeccg.util.bean;

import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.Converter;

import br.com.insejeccg.util.message.MessageResources;

/**
 * Provides a multi-thread internationalized BeanHelper
 * 
 * @author fabricio
 * 
 */
@SuppressWarnings("unchecked")
public class BeanHelperUtil {

	private static final ThreadLocal<BeanHelper> threadBeanHelper = new ThreadLocal<BeanHelper>();

	/**
	 * If your application is multi-thread, you can set a locale and a message
	 * file to the thread context
	 * 
	 * @param locale
	 * @param messageResources
	 */
	public static void initContext(Locale locale,
			MessageResources messageResources) {
		BeanHelper beanHelper = createBeanHelper();
		beanHelper.setLocale(locale);
		beanHelper.setMessageRecourse(messageResources);
		setCurrentBeanHelper(beanHelper);
	}

	protected static BeanHelper getCurrentBeanHelper() {
		BeanHelper bean = (BeanHelper) threadBeanHelper.get();
		if (bean == null) {
			bean = createBeanHelper();
			setCurrentBeanHelper(bean);
		}
		return bean;
	}

	private static void setCurrentBeanHelper(BeanHelper bean) {
		threadBeanHelper.set(bean);
	}

	public static Locale getLocale() {
		return getCurrentBeanHelper().getLocale();
	}

	public static MessageResources getMessageResources() {
		return getCurrentBeanHelper().getMessageResources();
	}

	public static BeanHelper createBeanHelper() {
		return new BeanHelper();
	}

	public static void populate(Object object, Map<Object, Object> map)
			throws IllegalAccessException, InvocationTargetException {
		getCurrentBeanHelper().populate(object, map);
	}

	public static void copyProperties(Object dest, Object source)
			throws IllegalAccessException, InvocationTargetException {
		getCurrentBeanHelper().copyProperties(dest, source);
	}
	public static void copyProperty(Object dest,String name, Object source)
			throws IllegalAccessException, InvocationTargetException {
		getCurrentBeanHelper().copyProperty(dest, name, source);
	}

	public static void setProperty(Object dest, String property, Object value)
			throws IllegalAccessException, InvocationTargetException {
		getCurrentBeanHelper().setProperty(dest, property, value);
	}

	public static Object getProperty(Object dest, String property)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {
		return getCurrentBeanHelper().getProperty(dest, property);
	}

	public static Map describe(Object bean) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		return getCurrentBeanHelper().describe(bean);
	}

	public static String convert(Object value) {
		return getCurrentBeanHelper().getConvertUtils().convert(value);
	}

	public static <T> T convert(String value, Class<T> type) {
		return (T) getCurrentBeanHelper().getConvertUtils()
				.convert(value, type);
	}

	public static Converter lookup(Class type) {
		return getCurrentBeanHelper().getConvertUtils().lookup(type);
	}

	public static ConvertUtilsBean getConvertUtils() {
		return getCurrentBeanHelper().getConvertUtils();
	}

	public static ConvertUtilsBean register() {
		return getCurrentBeanHelper().getConvertUtils();
	}

	public static void register(Class clazz, Converter converter) {
		getCurrentBeanHelper().register(clazz, converter);
	}

}
